<template>
    <div class="ai-chat-page" @click="showAiChat = true">
        <img :src="AiImage" alt="" />
    </div>

    <el-drawer v-model="showAiChat" :modal="false" :with-header="false" size="400px">
        <!-- 对话区域内容 -->
        <div id="chat-content">
            <!-- 对话内容 -->
            <n-scrollbar>
                <div class="content">
                    <div class="message-container" ref="messageContainer">
                        <!-- 欢迎消息 -->
                        <div v-if="messages.length === 0" class="welcome-message">
                            <div class="message-bubble ai">
                                <div class="message-avatar">
                                    <img style="width: 30px;height: 25px;" :src="AiImage" alt="AI" />
                                </div>
                                <div class="message-content">
                                    <div class="message-text">你好！我是AI助手，有什么可以帮你的吗？</div>
                                </div>
                            </div>
                        </div>

                        <!-- 历史消息 -->
                        <div v-for="(message, index) in messages" :key="message.id"
                            :class="['message-bubble', message.role]">

                            <!-- AI消息：头像在左侧 -->
                            <div v-if="message.role === 'ai'" class="message-avatar ai-avatar">
                                <img style="width: 30px;height: 25px;" :src="AiImage" alt="AI" />
                            </div>

                            <!-- 消息内容 -->
                            <div :class="['message-content', message.role]">
                                <div class="message-text" v-html="formatMessage(message.content)"></div>
                                <div v-if="message.role === 'ai'" class="message-time">
                                    {{ formatTime(message.timestamp) }}
                                </div>
                            </div>

                            <!-- 用户消息：头像在右侧 -->
                            <div v-if="message.role === 'user'" class="message-avatar user-avatar">
                                <div class="user-avatar"><n-avatar :src="userStore().userInfo.avatar"></n-avatar></div>
                            </div>
                        </div>

                        <!-- 用户刚发送的消息 -->
                        <div v-if="pendingUserMessage" class="message-bubble user">
                            <div class="message-content">
                                <div class="message-text" v-html="formatMessage(pendingUserMessage)"></div>
                            </div>
                            <div class="message-avatar">
                                <div class="user-avatar"><n-avatar :src="userStore().userInfo.avatar"></n-avatar></div>
                            </div>
                        </div>

                        <!-- 实时流式响应显示 -->
                        <div v-if="isStreaming" class="message-bubble ai streaming">
                            <div class="message-avatar">
                                <img style="width: 30px;height: 25px;" :src="AiImage" alt="AI" />
                            </div>
                            <div class="message-content">
                                <div class="message-text" v-html="formatMessage(aiResponse)"></div>
                                <div class="typing-indicator">
                                    <span></span>
                                    <span></span>
                                    <span></span>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </n-scrollbar>

            <!-- 输入框 -->
            <div class="dispose-inp">
                <div class="input-area">
                    <el-input v-model="inputMessage" placeholder="输入你的问题..." :disabled="isStreaming"
                        @keyup.enter="sendMessage" class="message-input">
                        <template #append>
                            <el-button @click="sendMessage" :loading="isStreaming"
                                :disabled="!inputMessage.trim() || isStreaming" class="send-button">
                                <svg t="1756619876957" class="icon" viewBox="0 0 1024 1024" version="1.1"
                                    xmlns="http://www.w3.org/2000/svg" p-id="1485" width="16" height="16">
                                    <path
                                        d="M392.021333 925.013333a34.133333 34.133333 0 0 1-34.133333-34.133333V579.242667c0-10.24 4.608-19.968 12.629333-26.453334l276.48-224.085333a34.0992 34.0992 0 0 1 43.008 52.906667L426.154667 595.456v192.853333l82.944-110.592c10.069333-13.482667 28.672-17.578667 43.52-9.557333l137.557333 73.728L853.333333 156.16c3.242667-11.434667-3.413333-18.602667-6.485333-21.162667-3.072-2.56-11.093333-7.850667-21.845333-2.901333L206.336 422.4l80.213333 46.08c16.384 9.386667 22.016 30.208 12.629334 46.592s-30.208 22.016-46.592 12.629333l-137.045334-78.677333a33.979733 33.979733 0 0 1-17.066666-31.061333c0.512-12.8 8.021333-24.064 19.626666-29.525334L795.989333 70.314667c31.744-14.848 68.096-10.069333 94.890667 12.629333a87.790933 87.790933 0 0 1 28.16 91.477333L744.277333 801.28a34.082133 34.082133 0 0 1-48.981333 20.821333L546.133333 742.058667l-126.805333 169.301333c-6.656 8.704-16.896 13.653333-27.306667 13.653333z"
                                        :fill="isStreaming ? '#ccc' : '#231815'" p-id="1486"></path>
                                </svg>
                            </el-button>
                        </template>
                    </el-input>
                </div>
            </div>
        </div>
    </el-drawer>
</template>

<script setup lang="ts">
import { nextTick, onMounted, ref, watch } from "vue";
import { ElMessage } from "element-plus";
import { XStream } from 'ant-design-x-vue'
import { userStore } from "@/store/userStore";


const showAiChat = ref<boolean>(false);
const AiImage = ref<string>("https://free.picui.cn/free/2025/08/16/68a085c4bbe65.png");
const messageContainer = ref<HTMLElement | null>(null);

// 存储用户与ai的对话信息
const inputMessage = ref<string>("");
const pendingUserMessage = ref<string>(""); // 待发送的用户消息
const messages = ref<Array<{
    role: string;
    content: string;
    id: number;
    timestamp: number;
}>>([]);
const aiResponse = ref('');
const isStreaming = ref(false);
const abortController = ref<AbortController | null>(null);

// 格式化消息内容（防止XSS攻击）
const formatMessage = (text: string): string => {
    return text
        .replace(/&/g, '&amp;')
        .replace(/</g, '&lt;')
        .replace(/>/g, '&gt;')
        .replace(/"/g, '&quot;')
        .replace(/'/g, '&#039;')
        .replace(/\n/g, '<br>');
};

// 格式化时间
const formatTime = (timestamp: number): string => {
    return new Date(timestamp).toLocaleTimeString('zh-CN', {
        hour: '2-digit',
        minute: '2-digit'
    });
};

// 自动滚动到底部
const scrollToBottom = () => {
    nextTick(() => {
        if (messageContainer.value) {
            messageContainer.value.scrollTop = messageContainer.value.scrollHeight;
        }
    });
};

// 发送消息
const sendMessage = async (): Promise<void> => {
    if (!inputMessage.value.trim() || isStreaming.value) return;

    const userMessage = inputMessage.value.trim();
    pendingUserMessage.value = userMessage;
    inputMessage.value = "";

    try {
        await chatWithAi(userMessage);
    } catch (error) {
        console.error("发送消息失败:", error);
        ElMessage.error("发送消息失败");
    }
};

// 用户向ai发送信息
const chatWithAi = async (userMessage: string): Promise<void> => {
    const url = "http://localhost:7070/ai-chat/flux-stream";

    // 创建AbortController用于取消请求
    abortController.value = new AbortController();
    isStreaming.value = true;
    aiResponse.value = '';

    try {
        const response = await fetch(url, {
            method: "POST",
            headers: {
                "Content-Type": "application/json"
            },
            body: JSON.stringify({ userMessage }),
            signal: abortController.value.signal
        });

        if (!response.ok) {
            throw new Error(`HTTP错误! 状态码: ${response.status}`);
        }

        const readableStream = response.body;
        if (!readableStream) {
            throw new Error('未接收到可读流');
        }

        // 🌟 使用 XStream 处理流数据
        for await (const chunk of XStream({
            readableStream: readableStream,
        })) {
            console.log('收到数据块:', chunk);

            // 处理流式数据
            if (chunk.data) {
                try {
                    const parsedData = JSON.parse(chunk.data);
                    if (parsedData.content) {
                        aiResponse.value += parsedData.content;
                    } else if (parsedData.message) {
                        aiResponse.value += parsedData.message;
                    } else {
                        aiResponse.value += chunk.data;
                    }
                } catch (e) {
                    aiResponse.value += chunk.data;
                }
            } else if (typeof chunk === 'string') {
                aiResponse.value += chunk;
            }

            // 添加打字机效果延迟
            await new Promise(resolve => setTimeout(resolve, 20));
        }

        // 流式响应完成后，保存消息
        if (aiResponse.value) {
            messages.value.push({
                role: 'user',
                content: pendingUserMessage.value,
                id: Date.now(),
                timestamp: Date.now()
            });

            messages.value.push({
                role: 'ai',
                content: aiResponse.value,
                id: Date.now() + 1,
                timestamp: Date.now()
            });

            pendingUserMessage.value = "";
            ElMessage.success('AI响应完成');
        }

    } catch (error: any) {
        if (error.name === 'AbortError') {
            console.log('请求已取消');
        } else {
            console.error("发送消息失败:", error);
            ElMessage.error("发送消息失败");

            // 如果出错，仍然保存用户消息
            if (pendingUserMessage.value) {
                messages.value.push({
                    role: 'user',
                    content: pendingUserMessage.value,
                    id: Date.now(),
                    timestamp: Date.now()
                });
                pendingUserMessage.value = "";
            }
        }
    } finally {
        isStreaming.value = false;
        aiResponse.value = '';
        abortController.value = null;
    }
};

// 取消当前请求
const cancelRequest = () => {
    if (abortController.value) {
        abortController.value.abort();
        isStreaming.value = false;
        aiResponse.value = '';
        pendingUserMessage.value = "";
    }
};

// 监听消息变化，自动滚动
watch([messages, aiResponse, pendingUserMessage], scrollToBottom, { deep: true });

// 组件卸载时取消请求
onMounted(() => {
    window.addEventListener('beforeunload', cancelRequest);
});

</script>

<style scoped lang="scss">
* {
    padding: 0;
    margin: 0;
    box-sizing: border-box;
}

.ai-chat-page {
    width: 30px;
    height: 30px;
    -webkit-app-region: no-drag;
    cursor: pointer;
    transition: transform 0.2s ease;

    &:hover {
        transform: scale(1.1);
    }

    img {
        width: 100%;
        height: 100%;
        object-fit: cover;
        border-radius: 50%;
    }
}

.el-drawer {
    #chat-content {
        height: 100%;
        display: flex;
        flex-direction: column;
        background: #f8f9fa;

        .content {
            flex: 1;
            overflow-y: auto;
            padding: 16px;
            // background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);

            .message-container {
                max-width: 800px;
                margin: 0 auto;

                .welcome-message {
                    margin-bottom: 20px;
                    opacity: 0;
                    animation: fadeIn 0.6s ease forwards;
                }

                .message-bubble {
                    display: flex;
                    margin-bottom: 16px;
                    animation: slideIn 0.3s ease forwards;

                    &.user {
                        justify-content: flex-end;
                        align-items: flex-start;
                        // flex-direction: row-reverse;

                        .message-content {
                            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
                            color: white;
                            margin-left: 12px;

                            .message-time {
                                color: rgba(255, 255, 255, 0.7);
                            }
                        }
                    }

                    &.ai {
                        justify-content: flex-start;
                        align-items: flex-start;

                        .message-content {
                            background: white;
                            color: #333;
                            margin-right: 12px;
                            box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);

                            .message-time {
                                color: #666;
                            }
                        }
                    }

                    .message-avatar {
                        width: 40px;
                        height: 40px;
                        border-radius: 50%;
                        overflow: hidden;
                        flex-shrink: 0;

                        img {
                            width: 100%;
                            height: 100%;
                            object-fit: cover;
                        }

                        .user-avatar {
                            width: 100%;
                            height: 100%;
                            display: flex;
                            align-items: center;
                            justify-content: center;
                            background: #ddd;
                            font-size: 20px;
                        }
                    }

                    .message-content {
                        max-width: 70%;
                        padding: 12px 16px;
                        border-radius: 18px;
                        position: relative;

                        .message-text {
                            line-height: 1.5;
                            word-wrap: break-word;
                        }

                        .message-time {
                            font-size: 12px;
                            margin-top: 4px;
                            text-align: right;
                        }
                    }

                    &.streaming {
                        .message-content {
                            min-height: 40px;
                        }
                    }
                }
            }
        }

        .dispose-inp {
            padding: 16px;
            background: white;
            border-top: 1px solid #e0e0e0;

            .input-area {
                .message-input {
                    :deep(.el-input-group__append) {
                        background: transparent;
                        border: none;
                        padding: 0;
                    }
                }

                .send-button {
                    height: 32px;
                    padding: 0 12px;
                    border: none;
                    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
                    color: white;
                    transition: all 0.3s ease;

                    &:hover:not(:disabled) {
                        transform: translateY(-1px);
                        box-shadow: 0 4px 12px rgba(102, 126, 234, 0.4);
                    }

                    &:disabled {
                        background: #ccc;
                        cursor: not-allowed;
                    }
                }
            }
        }
    }
}

.typing-indicator {
    display: flex;
    align-items: center;
    padding: 8px 0;
    gap: 4px;

    span {
        width: 6px;
        height: 6px;
        border-radius: 50%;
        background: #999;
        animation: typing 1.4s infinite ease-in-out;

        &:nth-child(1) {
            animation-delay: 0s;
        }

        &:nth-child(2) {
            animation-delay: 0.2s;
        }

        &:nth-child(3) {
            animation-delay: 0.4s;
        }
    }
}

@keyframes typing {

    0%,
    60%,
    100% {
        transform: translateY(0);
        opacity: 0.4;
    }

    30% {
        transform: translateY(-5px);
        opacity: 1;
    }
}

@keyframes fadeIn {
    from {
        opacity: 0;
        transform: translateY(10px);
    }

    to {
        opacity: 1;
        transform: translateY(0);
    }
}

@keyframes slideIn {
    from {
        opacity: 0;
        transform: translateX(-20px);
    }

    to {
        opacity: 1;
        transform: translateX(0);
    }
}

@media (max-width: 768px) {
    .el-drawer {
        width: 100% !important;
    }

    .message-content {
        max-width: 85% !important;
    }
}
</style>